home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacGofer 0.22d / MacGofer Sources / commonui.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-25  |  14.0 KB  |  533 lines  |  [TEXT/MPS ]

  1. /* --------------------------------------------------------------------------
  2.  * commonui.c:  Copyright (c) Mark P Jones 1991-1993.   All rights reserved.
  3.  *              See goferite.h for details and conditions of use etc...
  4.  *              Gofer version 2.28 January 1993
  5.  *
  6.  * Parts of user interface common to both compiler and interpreter.
  7.  * ------------------------------------------------------------------------*/
  8.  
  9. #if MPW
  10. #pragma segment UI
  11. #endif
  12.  
  13. /* --------------------------------------------------------------------------
  14.  * Local function prototypes:
  15.  * ------------------------------------------------------------------------*/
  16.  
  17. static Void   local toggleSet          Args((Char,Bool));
  18. static Void   local togglesIn          Args((Bool));
  19. static Void   local showMemOpts          Args((Void));
  20. static Void   local optionInfo          Args((Void));
  21. static Void   local processOption     Args((String));
  22. static Int    local argToInt          Args((String *));
  23.  
  24. static Void   local loadProject       Args((String));
  25. static Void   local clearProject      Args((Void));
  26. static Void   local addScriptName     Args((String));
  27. #if !MAC
  28. static Void   local addScript          Args((String,Long));
  29. static Void   local forgetScriptsFrom Args((Module));
  30. #else
  31. static Void   local addScript          Args((Int,Int));
  32.        Void         forgetScriptsFrom Args((Module));
  33. #endif
  34.  
  35. static Void   local setLastEdit       Args((String,Int));
  36.  
  37. static Void   local failed          Args((Void));
  38.  
  39. static String local strCopy          Args((String));
  40. static Int    local substr          Args((String,String));
  41.  
  42. /* --------------------------------------------------------------------------
  43.  * Local data areas:
  44.  * ------------------------------------------------------------------------*/
  45.  
  46. #if !MAC
  47. static String scriptName[NUM_MODULES];    /* Script file names           */
  48. #endif
  49.  
  50. static Int    numScripts;        /* Number of scripts loaded       */
  51.  
  52. #if !MAC
  53. static Int    namesUpto;        /* Number of script names set       */
  54.  
  55. static String currProject = 0;        /* Name of current project file       */
  56. static Bool   projectLoaded = FALSE;    /* TRUE => project file loaded       */
  57. #endif
  58.  
  59. static String scriptFile;        /* Name of current script (if any) */
  60.  
  61. static Bool   useDots    = DOT_DEFAULT;    /* TRUE => use dots in progress    */
  62. static String lastEdit     = 0;        /* Name of file to edit (if any)   */
  63. static Int    lastLine     = 0;        /* Editor line number (if possible)*/
  64. #if MAC
  65. static short  lastVol    = 0;        /* Volume of last edited file       */
  66. static long   lastDir    = 0;        /* Directory of last edited file   */
  67. #endif
  68.  
  69. static String prompt     = 0;        /* Prompt string (gofer only)       */
  70. static String outputFile = 0;        /* User spec. output file (gofc)   */
  71.  
  72. #if MAC
  73. extern int  literateModule;        /* Is this module literate       */        
  74. extern int  moduleCoerceNumLiterals;    /* Does this module coerce nos.       */
  75. extern int  errorLine;            /* Line number for last error       */
  76. extern int  errorMod;            /* File name for last error       */
  77. #endif
  78.  
  79. /* --------------------------------------------------------------------------
  80.  * Command line options:
  81.  * ------------------------------------------------------------------------*/
  82.  
  83. #if !MAC
  84.  
  85. struct options {            /* command line option toggles       */
  86.     char   c;                /* table defined in main app.       */
  87.     String description;
  88.     Int    *flag;
  89. };
  90. extern struct options toggle[], memopt[];
  91.  
  92. static Void local toggleSet(c,state)    /* Set command line toggle       */
  93. Char c;
  94. Bool state; {
  95.     Int i;
  96.     for (i=0; toggle[i].c; ++i)
  97.     if (toggle[i].c == c) {
  98.         *toggle[i].flag = state;
  99.         return;
  100.     }
  101.     ERROR(0) "Unknown toggle `%c'", c
  102.     EEND;
  103. }
  104.  
  105.  
  106. static Void local memoryoption(c,sp)    /* Set Memory option       */
  107. char c;
  108. String *sp; {
  109.     Int i;
  110.     for (i=0; memopt[i].c; ++i)
  111.     if (memopt[i].c == c) {
  112.         *memopt[i].flag = argToInt(sp);
  113.         return;
  114.     }
  115.     ERROR(0) "Unknown memory option `%c'", c
  116.     EEND;
  117. }
  118.  
  119.  
  120. static Void local showMemOpts()        /* Print current list of memory options*/
  121. {
  122.     Int i;
  123.     for (i=0; memopt[i].c; ++i)
  124.       printf("-m%c%u ",memopt[i].c,*memopt[i].flag);
  125. }
  126.  
  127. static Void local togglesIn(state)    /* Print current list of toggles in*/
  128. Bool state; {                /* given state               */
  129.     Int count = 0;
  130.     Int i;
  131.     for (i=0; toggle[i].c; ++i)
  132.     if (*toggle[i].flag == state) {
  133.         if (count==0)
  134.         putchar(state ? '+' : '-');
  135.         putchar(toggle[i].c);
  136.         count++;
  137.     }
  138.     if (count>0)
  139.     putchar(' ');
  140. }
  141.  
  142. static Void local optionInfo() {    /* Print information about command */
  143.     static String fmts = "%-5s%s\n";    /* line settings           */
  144.     static String fmtc = "%-5c%s\n";
  145.     Int    i;
  146.  
  147.     printf("TOGGLES: groups begin with +/- to turn options on/off resp.\n");
  148.     for (i=0; toggle[i].c; ++i)
  149.     printf(fmtc,toggle[i].c,toggle[i].description);
  150.  
  151.     printf("MEMORY OPTIONS: usage -m`z'num where `z' is the option\n");
  152.     for (i=0; memopt[i].c; ++i)
  153.     printf(fmtc,memopt[i].c,memopt[i].description);
  154.  
  155.     printf("\nOTHER OPTIONS: (leading + or - makes no difference)\n");
  156.     printf(fmts,"hnum","Set heap size (cannot be changed within Gofer)");
  157.     printf(fmts,"pstr","Set prompt string to str");
  158.     printf(fmts,"rstr","Set repeat last expression string to str");
  159. #ifdef TECH_TOGGLES
  160.     printf(fmts,"xnum","Set maximum depth for evidence search");
  161. #endif
  162.  
  163.     printf("\nCurrent settings: ");
  164.     togglesIn(TRUE);
  165.     togglesIn(FALSE);
  166.     showMemOpts();
  167. #ifdef TECH_TOGGLES
  168.     printf("-h%d -p%s -x%d -r%s\n",heapSize,prompt,maxEvidLevel,repeatStr);
  169. #else
  170.     printf("-h%d -p%s -r%s\n",heapSize,prompt,repeatStr);
  171. #endif
  172. }
  173.  
  174. static Void local processOption(s)    /* process option string s       */
  175. String s; {
  176.     Bool state = (s[0]=='+' ? TRUE : FALSE);
  177.  
  178.     while (*++s)
  179.     switch (*s) {
  180.         case 'n' : if (s[1]) {
  181.                if (outputFile) free(outputFile);
  182.                outputFile = strCopy(s+1);
  183.                }
  184.                return;
  185.  
  186.         case 'p' : if (s[1]) {
  187.                if (prompt) free(prompt);
  188.                prompt = strCopy(s+1);
  189.                }
  190.                return;
  191.  
  192.         case 'r' : if (s[1]) {
  193.                if (repeatStr) free(repeatStr);
  194.                repeatStr = strCopy(s+1);
  195.                }
  196.                return;    
  197.  
  198.         case 'h' : if (heapBuilt()) {
  199.                ERROR(0) "Cannot change heap size"
  200.                EEND;
  201.                }
  202.                heapSize = argToInt(&s);
  203.                if (heapSize<MINIMUMHEAP)
  204.                heapSize = MINIMUMHEAP;
  205. #ifdef MAXIMUMHEAP
  206. #if MAXIMUMHEAP
  207.                else if (heapSize>MAXIMUMHEAP)
  208.                heapSize = MAXIMUMHEAP;
  209. #endif
  210. #endif
  211.                break;
  212.  
  213. #ifdef TECH_TOGGLES
  214.         case 'x' : maxEvidLevel = argToInt(&s);
  215.                break;
  216. #endif
  217.  
  218.         case 'm':  memoryoption(*++s,&s);
  219.                    break;
  220.  
  221.         default  : toggleSet(*s,state);
  222.                break;
  223.     }
  224. }
  225.  
  226. static Int local argToInt(sp)        /* read integer from argument str  */
  227. String *sp; {
  228.     Int num = 0;
  229.     while (isascii((*sp)[1]) && isdigit((*sp)[1])) {
  230.     num = 10*num + (*(++*sp) - '0');
  231.     }
  232.     return num;
  233. }
  234. #endif
  235.  
  236. /* --------------------------------------------------------------------------
  237.  * Loading project and script files:
  238.  * ------------------------------------------------------------------------*/
  239.  
  240. #if !MAC
  241.  
  242. static Void local loadProject(s)    /* Load project file          */
  243. String s; {
  244.     clearProject();
  245.     currProject = s;
  246.     projInput(currProject);
  247.     scriptFile = currProject;
  248.     forgetScriptsFrom(1);
  249.     while (s=readFilename())
  250.     addScriptName(s);
  251.     if (namesUpto<=1) {
  252.     ERROR(0) "Empty project file"
  253.     EEND;
  254.     }
  255.     scriptFile    = 0;
  256.     projectLoaded = TRUE;
  257. }
  258.  
  259. static Void local clearProject() {     /* clear name for current project   */
  260.     if (currProject)
  261.     free(currProject);
  262.     currProject   = 0;
  263.     projectLoaded = FALSE;
  264. }
  265.  
  266. static Void local addScriptName(s)     /* add script name to list of files */
  267. String s; {                   /* to be read in ...           */
  268.     if (s[0]=='-' || s[0]=='+')
  269.     processOption(s);
  270.     else if (namesUpto>=NUM_MODULES) {
  271.     ERROR(0) "Too many script files (maximum of %d allowed)",
  272.          NUM_MODULES
  273.     EEND;
  274.     }
  275.     else
  276.     scriptName[namesUpto++] = strCopy(s);
  277. }
  278.  
  279. static Void local addScript(fname,len) /* read single script file       */
  280. String fname;                   /* name of script file           */
  281. Long   len; {                   /* length of script file        */
  282.     scriptFile = fname;
  283.  
  284.     printf("Reading script file \"%s\":\n",fname);
  285.     setLastEdit(fname,0);
  286.  
  287.     parseScript(fname,len);           /* process script file           */
  288.     checkDefns();
  289.     if (numScripts==0)            /* initialisation to be done once  */
  290.     everybody(PRELUDE);        /* prelude Tycons and Classes known*/
  291.     typeCheckDefns();    
  292.     compileDefns();
  293.  
  294.     scriptFile = 0;
  295. }
  296.  
  297. static Void local forgetScriptsFrom(scno)/* remove scripts from system       */
  298. Module scno; {
  299.     Module i;
  300.     for (i=scno; i<namesUpto; ++i)
  301.     if (scriptName[i])
  302.         free(scriptName[i]);
  303.     dropModulesFrom(scno-1);         /* don't count prelude as module  */
  304.     namesUpto = scno;
  305.     if (numScripts>0)
  306.     numScripts = scno;
  307. }
  308.  
  309. #else    /* !MAC */
  310.  
  311. extern char *scriptname();
  312.  
  313. static Void local addScript(mod,i)
  314. int mod,i;
  315. {
  316.     char *fname;
  317.     long len = getscriptlen(mod);
  318.     
  319.     CStackBase = (int *) &len;            /* Set stack base for Gofer GC */
  320.     
  321.     scriptFile = fname = scriptname(mod);
  322.     setLastEdit(fname,0);
  323.     errorMod = i;
  324.     printf("Reading script file \"%s\":\n",fname);
  325.     changedir(mod);
  326.     literateModule = isliterate(mod);
  327.     parseScript(fname,len);           /* process script file           */
  328.     literateModule = FALSE;
  329.     resetdir();
  330.  
  331.     checkDefns();
  332.     if (numScripts==0)            /* initialisation to be done once  */
  333.     everybody(PRELUDE);        /* prelude Tycons and Classes known*/
  334.  
  335.     moduleCoerceNumLiterals = ishaskmodule(mod);
  336.     typeCheckDefns();
  337.     moduleCoerceNumLiterals = FALSE;
  338.     compileDefns();
  339.     scriptFile = 0;
  340. }
  341.  
  342. Void forgetScriptsFrom(scno)        /* remove scripts from system       */
  343. Module scno; {
  344.     if(numScripts == 0)
  345.       scno = 0;
  346.     dropModulesFrom(scno);         /* don't count prelude as module  */
  347.     numScripts = scno;
  348. }
  349.  
  350. #endif
  351.  
  352.  
  353. #if MAC
  354. /**************** Two magic memory locations from mac.h *****************/
  355.  
  356. #define SFSaveDisk     0x214        /* Volume number (negative)      */
  357. #define CurDirStore     0x398        /* Current directory        */
  358. #endif
  359.  
  360.  
  361. static Void local setLastEdit(fname,line)/* keep name of last file to edit */
  362. String fname;
  363. Int    line; {
  364.     if (lastEdit)
  365.     free(lastEdit);
  366.     lastEdit = strCopy(fname);
  367.     lastLine = line;
  368. #if MAC
  369.     errorLine = line;
  370.     lastDir =   *((long *)CurDirStore);
  371.     lastVol =   -1 * (*(short *)SFSaveDisk);
  372. #endif
  373. }
  374.  
  375. /* --------------------------------------------------------------------------
  376.  * Display progress towards goal:
  377.  * ------------------------------------------------------------------------*/
  378.  
  379. static Target currTarget;
  380. static Bool   aiming = FALSE;
  381. static Int    currPos;
  382. static Int    maxPos;
  383. static Int    charCount;
  384.  
  385. Void setGoal(what, t)               /* Set goal for what to be t       */
  386. String what;
  387. Target t; {
  388.     currTarget = (t?t:1);
  389.     aiming     = TRUE;
  390.     if (useDots) {
  391.     currPos = strlen(what);
  392.     maxPos  = getTerminalWidth() - 1;
  393.     printf("%s",what);
  394.       }
  395.      else
  396. #if !MPW
  397.     for (charCount=0; *what; charCount++)
  398.        putchar(*what++);
  399. #else
  400.      /* This is rather faster -- at least on the Mac, and since we don't need charCount, it's safe -- KH */
  401.     printf("%s...",what); 
  402. #endif
  403.     fflush(stdout);
  404. #if MAC
  405.     SpinCursor(0);            /* Start spinning that cursor */
  406.     Show_Cursor(HIDDEN_CURSOR);
  407. #endif
  408. }
  409.  
  410. Void soFar(t)                   /* Indicate progress towards goal   */
  411. Target t; {                   /* has now reached t           */
  412.     if (useDots) {
  413.     Int newPos = (Int)((maxPos * ((long)t))/currTarget);
  414.  
  415.     if (newPos>maxPos)
  416.         newPos = maxPos;
  417.  
  418.     if (newPos>currPos) {
  419.         do  {
  420.         putchar('.');
  421. #if MAC
  422.                 SpinCursor(4);        /* Spin the cursor some more */
  423. #endif
  424.         } while (newPos>++currPos);
  425.         fflush(stdout);
  426.     }
  427.     fflush(stdout);
  428.     }
  429. }
  430.  
  431. Void done() {                   /* Goal has now been achieved       */
  432.     if (useDots) {
  433.     while (maxPos>currPos++)
  434.       {
  435.         putchar('.');
  436. #if MAC
  437.             SpinCursor(4);    /* Last cursor spin */
  438. #endif
  439.       }
  440.     putchar('\n');
  441.     aiming = FALSE;
  442.     }
  443.     
  444.     /* 
  445.        Hmm.  This won't work on quite a lot of machines I've met, e.g. the Mac
  446.        where '\b' is a PRINTING character!  KH
  447.     */
  448.     else
  449. #if !MPW
  450.     for (; charCount>0; charCount--) {
  451.         putchar('\b');
  452.         putchar(' ');
  453.         putchar('\b');
  454.     }
  455. #else
  456.     printf("Done\n");
  457. #endif
  458.     fflush(stdout);
  459. }
  460.  
  461. static Void local failed() {           /* Goal cannot be reached due to    */
  462.     if (aiming) {               /* errors               */
  463.     aiming = FALSE;
  464.     putchar('\n');
  465.     fflush(stdout);
  466.     }
  467. }
  468.  
  469. /* --------------------------------------------------------------------------
  470.  * Send message to each component of system:
  471.  * ------------------------------------------------------------------------*/
  472.  
  473. Void everybody(what)        /* send command `what' to each component of*/
  474. Int what; {            /* system to respond as appropriate ...    */
  475.     machdep(what);        /* The order of calling each component is  */
  476.     storage(what);        /* important for the INSTALL command       */
  477.     input(what);
  478.     staticAnalysis(what);
  479.     typeChecker(what);
  480.     compiler(what);
  481.     machine(what);
  482.     builtIn(what);
  483. }
  484.  
  485. /* --------------------------------------------------------------------------
  486.  * Read value from environment variable:
  487.  * ------------------------------------------------------------------------*/
  488.  
  489. #if !MAC
  490. String fromEnv(var,def)        /* return value of:                */
  491. String var;            /*     environment variable named by var   */
  492. String def; {            /* or: default value given by def       */
  493.     String s = getenv(var);
  494.  
  495.     return (s ? s : def);
  496. }
  497. #endif
  498.  
  499. /* --------------------------------------------------------------------------
  500.  * String manipulation routines:
  501.  * ------------------------------------------------------------------------*/
  502.  
  503. static String local strCopy(s)           /* make malloced copy of a string   */
  504. String s; {
  505.     if (s) {
  506.     char *t,*r;
  507.     if ((t=(char *)malloc(strlen(s)+1))==0) {
  508.         ERROR(0) "String storage space exhausted"
  509.         EEND;
  510.     }
  511.     for (r=t; *r++ = *s++; )
  512.         ;
  513.     return t;
  514.     }
  515.     return s;
  516. }
  517.  
  518. static Int local substr(s1,s2)        /* find posn of substring s1 in s2 */
  519. String s1, s2; {            /* (naive implementation)       */
  520.     String t;
  521.  
  522.     for (t=s2; *t; t++) {
  523.     Int i = 0;
  524.         while (s1[i] && s1[i]==t[i])
  525.         i++;
  526.     if (s1[i]=='\0')
  527.         return t-s2;
  528.     }
  529.     return (-1);
  530. }
  531.  
  532. /*-------------------------------------------------------------------------*/
  533.